<template>
  <div>
    <NavigationBar title-text="个人资料" background-color="#f6f6f6" />
    <Message ref="message" />
    <Loading ref="loading" fullscreen />
    <Loading ref="uploading" fullscreen maskColor="rgba(255, 255, 255, 0.8)" />

    <div
      class="my-user-profile-container w-screen h-full pt-10rpx pb-30rpx flex-column bg-hex-f6f6f6"
      :style="{minHeight: `calc(100vh - ${navigationHeight}px)`}">
      <div class="profile-container w-full px-40rpx py-20rpx bg-white">
        <div class="profile-row w-full min-h-100rpx flex items-center flex-nowrap text-30rpx">
          <div class="flex-shrink-0 text-hex-555">
            头像
          </div>
          <div
            class="row-content min-w-60vw flex flex-grow-1 items-center justify-end ml-auto overflow-hidden text-black"
            @click="handleAvatarChange">
            <image
              class="avatar w-70rpx h-70rpx bg-hex-eee"
              :src="userProfile.avgPath"
              mode="aspectFill" />
            <i class="fas fa-angle-right" />
          </div>
        </div>
        <div class="profile-row w-full min-h-100rpx flex items-center flex-nowrap text-30rpx">
          <div class="flex-shrink-0 text-hex-555">
            用户名
          </div>
          <div
            class="row-content min-w-60vw flex flex-grow-1 items-center justify-end ml-auto overflow-hidden text-black">
            <div class="content">
              <input
                type="text"
                v-model="userProfile.username"
                maxlength="10"
                @focus="usernameTemp = userProfile.username"
                @blur="handleUsernameChange"
                @confirm="handleUsernameChange">
            </div>
            <i class="fas fa-angle-right" />
          </div>
        </div>
        <div class="profile-row w-full min-h-100rpx flex items-center flex-nowrap text-30rpx">
          <div class="flex-shrink-0 text-hex-555">
            姓名
          </div>
          <div
            class="row-content min-w-60vw flex flex-grow-1 items-center justify-end ml-auto overflow-hidden text-black">
            <div class="content">
              <input
                type="text"
                v-model="userProfile.realName"
                maxlength="10"
                @focus="usernameTemp = userProfile.realName"
                @blur="handleRealNameChange"
                @confirm="handleRealNameChange">
            </div>
            <i class="fas fa-angle-right" />
          </div>
        </div>
        <div class="profile-row w-full min-h-100rpx flex items-center flex-nowrap text-30rpx">
          <div class="flex-shrink-0 text-hex-555">
            性别
          </div>
          <div
            class="row-content min-w-60vw flex flex-grow-1 items-center justify-end ml-auto overflow-hidden text-black gender"
            @click="showGenderSelector = true">
            <div class="content">
              {{ formatGender(userProfile.gender) }}
            </div>
            <i class="fas fa-angle-right" />
            <u-select
              v-model="showGenderSelector"
              :list="[{label: '男', value: 1}, {label: '女', value: 2}]"
              confirm-color="#f4756b"
              :safe-area-inset-bottom="true"
              @confirm="handleGenderChange" />
          </div>
        </div>
        <div class="profile-row w-full min-h-100rpx flex items-center flex-nowrap text-30rpx">
          <div class="flex-shrink-0 text-hex-555">
            地区
          </div>
          <div
            class="row-content min-w-60vw flex flex-grow-1 items-center justify-end ml-auto overflow-hidden text-black"
            @click="showAreaSelector = true">
            <div class="content">
              {{ areaName }}
            </div>
            <i class="fas fa-angle-right" />
          </div>
        </div>
        <div class="profile-row w-full min-h-100rpx flex items-center flex-nowrap text-30rpx">
          <div class="flex-shrink-0 text-hex-555">
            绑定微信
          </div>
          <div
            class="row-content min-w-60vw flex flex-grow-1 items-center justify-end ml-auto overflow-hidden text-black">
            已绑定
          </div>
        </div>
        <div class="profile-row w-full min-h-100rpx flex items-center flex-nowrap text-30rpx">
          <div class="flex-shrink-0 text-hex-555">
            我的地址
          </div>
          <div
            class="row-content min-w-60vw flex flex-grow-1 items-center justify-end ml-auto overflow-hidden text-black"
            @click="gotoPage('/pages/address-book/address-book')">
            <i class="fas fa-angle-right" />
          </div>
        </div>
      </div>
      <div class="logout-button-container w-full px-50rpx mt-auto">
        <div
          class="btn__default w-full h-80rpx bg-primary text-center text-white transition-opacity duration-500"
          @click="logout">
          退出登录
        </div>
      </div>
    </div>
    <!-- 图片上传组件 -->
    <u-upload
      class="upload"
      ref="uploadRef"
      :action="avatarUploadUrl"
      :file-list="fileList"
      :form-data="uploadFormData"
      :max-size="10485760"
      :max-count="1"
      :show-tips="true"
      :limitType="['png', 'jpg', 'jpeg']"
      :source-type="uploadSourceType"
      @on-success="onUploadSuccess"
      @on-error="onUploadError"
      @on-oversize="onUploadOversize" />
    <SelectArea
      ref="selectAreaRef"
      v-model="showAreaSelector"
      :safe-area-inset-bottom="true"
      maskCloseAble
      @confirm="handleAreaChange" />
  </div>
</template>

<script setup lang="ts">
  import NavigationBar from '@/components/navigation-bar/src/navigation-bar.vue'
  import Message from '@/components/message/src/message.vue'
  import type { MessageMethod } from '@/components/message'
  import Loading from '@/components/loading/src/loading.vue'
  import type {LoadingMethod} from '@/components/loading'
  import SelectArea from '@/components/select-popup/select-area/src/select-area.vue'
  import type {SelectAreaMethod, SelectResult} from '@/components/select-popup/select-area'
  import type {ComputedRef} from 'vue'
  import {useSystemStore, useUserStore} from '@/store'
  import {gotoPage} from '@/common/utils'
  import {formatDateTime} from '@/common/filters'
  import {userApi} from '@/service/api'
  import {systemApi} from '../../service/api';
  import {TargetType} from '../../service/api/enum';
  import {getNoSymbolUuid} from '../../common/utils';

  const message = ref<InstanceType<typeof Message> & MessageMethod>(null)
  const loading = ref<InstanceType<typeof Loading> & LoadingMethod>(null)
  const uploading = ref<InstanceType<typeof Loading> & LoadingMethod>(null)
  const uploadRef = ref<any>(null)
  const selectAreaRef = ref<InstanceType<typeof SelectArea> & SelectAreaMethod>(null)

  const {navigationHeight} = storeToRefs(useSystemStore())
  const {userInfo} = storeToRefs(useUserStore())

  const userProfile = ref<any>({}) //个人资料信息
  const avatarUploadUrl = ref('http://127.0.0.1:3005/upload/avatar') //头像上传URL
  const usernameTemp = ref('') //用户名输入前的缓存
  const realNameTemp = ref('') //真实姓名输入前的缓存
  const descriptionTemp = ref('') //个人简介输入前的缓存
  const showGenderSelector = ref(false) //是否显示性别选择器
  const showBirthdaySelector = ref(false) //是否显示生日日期选择器
  const showAreaSelector = ref(false) //是否显示地区选择器
  const uploadSourceType = ref<Array<string>>(['album', 'camera']) //上传组件的图片来源（相册/相机）
  const action = ref('') //图片上传Url
  const fileList = ref([]) //发送图片的队列
  const uploadFormData = ref<Object>({fileId:userInfo.value?.userId})

  const init = (): void => {
    userApi.getCurrentUserInfo().then(({data}) => {
      useUserStore().setUserInfo(data)
      userProfile.value = data
    }).catch(error => {
      console.error(error)
      message.value.error({
        text: '获取个人信息失败',
        direction: 'top'
      })
    })
  }
  init()

  // 头像更改点击事件
  const handleAvatarChange = (): void => {
    uploadRef.value.selectFile()
  }

  // 用户名输入更改事件
  const handleUsernameChange = (e: CustomEvent): void => {
    if (!e.detail.value.replaceAll(/\s*/g, '')) {
      message.value.warning({
        text: '用户名不能为空',
        direction: 'top'
      })
    } else if (e.detail.value !== usernameTemp.value) {
      submitChange({
        userId: userProfile.value.userId,
        username: e.detail.value.replaceAll(/\s*/g, '')
      }).then(() => {
        userProfile.value.username = e.detail.value
      })
    }
  }

  // 真实姓名输入更改事件
  const handleRealNameChange = (e: CustomEvent): void => {
    if (!e.detail.value.replaceAll(/\s*/g, '')) {
      message.value.warning({
        text: '用户名不能为空',
        direction: 'top'
      })
    } else if (e.detail.value !== realNameTemp.value) {
      submitChange({
        userId: userProfile.value.userId,
        realName: e.detail.value.replaceAll(/\s*/g, '')
      }).then(() => {
        userProfile.value.realName = e.detail.value
      })
    }
  }

  type GenderList = {
    label: string
    value: number
  }
  // 性别更改回调事件
  const handleGenderChange = (gender: Array<GenderList>): void => {
    if (gender[0].value !== userProfile.value.gender) {
      submitChange({
        userId: userProfile.value.userId,
        gender: gender[0].value
      }).then(() => {
        userProfile.value.gender = gender[0].value
      })
    }
  }

  type Birthday = {
    year: string | number
    month: string | number
    day: string | number
  }
  // 出生日期更改回调事件
  const handleBirthdayChange = (birthday: Birthday): void => {
    if (`${birthday.year}-${birthday.month}-${birthday.day}` !== userProfile.value.birthday) {
      submitChange({
        userId: userProfile.value.userId,
        birthday: `${birthday.year}-${birthday.month}-${birthday.day}`
      }).then(() => {
        userProfile.value.birthday = `${birthday.year}-${birthday.month}-${birthday.day}`
      })
    }
  }

  // 个人简介输入更改事件
  const handleDescriptionChange = (e: CustomEvent): void => {
    if (e.detail.value !== descriptionTemp.value) {
      submitChange({
        userId: userProfile.value.userId,
        signature: e.detail.value.replaceAll(/\s*/g, '')
      }).then(() => {
        userProfile.value.signature = e.detail.value
      })
    }
  }

  // 地区更改回调事件
  const handleAreaChange = (area: SelectResult): void => {
    if (area.area?.code !== userProfile.value.areaCode) {
      submitChange({
        userId: userProfile.value.userId,
        areaCode: area.area?.code
      }).then(() => {
        userProfile.value.areaCode = area.area?.code
      })
    }
  }

  // 学校更改事件
  const handleSchoolChange = (): void => {
    // uni.navigateTo({
    //     url: '/pagesByUser/myUserProfile/subpages/schoolSearch/schoolSearch',
    //     events: {
    //         onSchoolSelected: data => {
    //             if (data) {
    //                 submitChange({
    //                     userId: userProfile.value.userId,
    //                     schoolId: data.schoolInfo.schoolId
    //                 }).then(() => {
    //                     userProfile.value.schoolName = data.schoolInfo.schoolName
    //                     userProfile.value.schoolId = data.schoolInfo.schoolId
    //                 })
    //             }
    //         }
    //     }
    // })
  }

  // 提交更改
  const submitChange = (data: any): Promise<void> => {
    return new Promise<void>(resolve => {
      userApi.updateUserInfo(data).then(() => {
        resolve()
      }).catch(err => {
        console.error(err)
        message.value.error({
          text: '修改失败',
          direction: 'top'
        })
      })
    })
  }

  // 上传图片前的钩子函数
  const beforeUpload = (index: number, list: Array<any>): Promise<void | string> => {
    return new Promise<void | string>((resolve, reject) => {
      uni.compressImage({
        src: list[0].url,
        quality: 80,
        success: res => {
          const tempPath = list[0].file.path
          const fileSuffix = tempPath.substr(tempPath.lastIndexOf('.'))
          uploading.value.startLoading()
          systemApi.getUploadSignature({targetTypeName: TargetType.USER_AVG}).then(signRes => {
            const signData = signRes.data
            action.value = `https://${signData?.uploadDomain}` //上传的url
            const key = `${signData?.keyPrefix}${getNoSymbolUuid()}${fileSuffix}` // 组合保存到云的文件路径
            if (signRes.success) {
              uploadFormData.value = {
                key: key,
                token: signData?.token
              }
              resolve()
            } else {
              reject()
              console.error('获取签名失败', signRes)
            }
          }).catch(err => {
            console.error('getUploadSignature错误', err)
            uni.showToast({
              title: '网络异常',
              icon: 'error',
              duration: 3000
            })
            uploadRef.value.clear()
            reject(err)
          })
        }
      })
    })
  }

  // 头像上传成功回调事件
  const onUploadSuccess = (data: any): void => {
    submitChange({
      userId: userProfile.value.userId,
      avgPath: data.data.data.imgUrl
    }).then(() => {
      userProfile.value.avgPath = data.url
    }).finally(() => {
      uploading.value.stopLoading()
      uploadRef.value.clear()
    })
  }

  //头像上传失败回调事件
  const onUploadError = (e: any): void => {
    console.error(e)
    uploading.value.stopLoading()
    message.value.error({
      text: '上传失败',
      direction: 'top'
    })
  }

  //头像上传超出大小限制回调事件
  const onUploadOversize = (): void => {
    uploading.value.stopLoading()
    message.value.warning({
      text: '图片超出10MB限制',
      direction: 'top'
    })
  }

  // 退出登录
  const logout = (): void => {
    useUserStore().logOut()
    gotoPage('/pages/my-page/my-page', 'switchTab')
  }

  // 地区名称（根据地区编号查询）
  const areaName: ComputedRef<string> = computed(() => {
    if (!!userProfile.value.areaCode) {
      const queryResult = selectAreaRef.value.queryAreaName(userProfile.value.areaCode)
      return queryResult ? `${queryResult[0]}${queryResult[1]}${queryResult[2]}` : ''
    } else return ''
  })

  watch(
    () => userProfile.value.realName,
    nval => userProfile.value.realName = nval.replaceAll(/\s*/g, '')
  )

  watch(
    () => userProfile.value.username,
    nval => userProfile.value.username = nval.replaceAll(/\s*/g, '')
  )

  watch(
    () => userProfile.value.signature,
    nval => userProfile.value.signature = nval.replaceAll(/\s*/g, '')
  )

  // 格式化性别显示
  function formatGender(gender: 1 | 2): string {
    return gender == 1 ? '男' : gender == 2 ? '女' : ''
  }

  onBeforeUnmount((): void => {
    if (!!userInfo.value) {
      userApi.getCurrentUserInfo().then(({data}) => {
        useUserStore().setUserInfo(data)
      }).catch(err => {
        console.error(err)
      })
    }
  })
</script>

<style scoped lang="scss">
  @import "my-user-profile";
</style>
